﻿/* PN264 - A Parallel H.264 Encoding Utility
 * Copyright © 2009 PN264 Development Team
 *
 * This software is released the terms and conditions of the MIT License,
 * a copy of which can be found in the License.txt file.
 *
 * Contributors:
 * Will 'AnarkiNet' Shelley (AnarkiNet@gmail.com)
 */
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace PN264.Controls
{
    /// <summary>
    /// Provides a control that displays a list of jobs.
    /// </summary>
    public partial class JobList : UserControl
    {
        #region Constructors
        /// <summary>
        /// Initializes a new instance of the <see cref="JobList"/> class.
        /// </summary>
        public JobList()
        {
            InitializeComponent();

            this.JobFilter = JobStatus.All;
            this.SelectedJob = null;
        }
        #endregion
        #region Events
        /// <summary>
        /// Raised when the value of the <see cref="JobList.JobFilter"/>
        /// property changes.
        /// </summary>
        public event EventHandler JobFilterChanged;
        /// <summary>
        /// Raised when the value of the <see cref="JobList.SelectedJob"/>
        /// property changes.
        /// </summary>
        public event EventHandler<SelectedJobChangedEventArgs> SelectedJobChanged;
        #endregion
        #region Fields
        private JobStatus jobFilter;
        private Job selectedJob;
        private readonly List<Job> jobs = new List<Job>();
        #endregion
        #region Methods
        /// <summary>
        /// Adds a <see cref="Job"/> to the current <see cref="JobList"/>.
        /// </summary>
        /// <param name="job">The <see cref="Job"/> to add.</param>
        public void AddJob(Job job)
        {
            if (job == null)
            {
                throw new ArgumentNullException("job");
            }
            this.jobs.Add(job);
            this.jobListView.Items.Add(this.GetItemFromJob(job));
        }
        private void OnJobFilterChanged(EventArgs e)
        {
            if (this.JobFilterChanged != null)
            {
                this.JobFilterChanged(this, e);
            }
            this.showCanceledMenuItem.Checked = (this.JobFilter & JobStatus.Canceled) == JobStatus.Canceled;
            this.showCompletedMenuItem.Checked = (this.JobFilter & JobStatus.Completed) == JobStatus.Completed;
            this.showDisabledMenuItem.Checked = (this.JobFilter & JobStatus.Disabled) == JobStatus.Disabled;
            this.showFailedMenuItem.Checked = (this.JobFilter & JobStatus.Failed) == JobStatus.Failed;
            this.showPausedMenuItem.Checked = (this.JobFilter & JobStatus.Paused) == JobStatus.Paused;
            this.showProcessingMenuItem.Checked = (this.JobFilter & JobStatus.Processing) == JobStatus.Processing;
            this.showWaitingMenuItem.Checked = (this.JobFilter & JobStatus.Waiting) == JobStatus.Waiting;

            this.UpdateListContents();
        }
        private void showAllMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = JobStatus.All;
        }

        private void showDisabledMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Disabled;
        }

        private void showWaitingMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Waiting;
        }

        private void showProcessingMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Processing;
        }

        private void showPausedMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Paused;
        }

        private void showCompletedMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Completed;
        }

        private void showFailedMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Failed;
        }

        private void showCanceledMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = this.JobFilter ^ JobStatus.Canceled;
        }

        private void showNoneMenuItem_Click(object sender, EventArgs e)
        {
            this.JobFilter = JobStatus.None;
        }
        private ListViewItem GetItemFromJob(Job job)
        {
            return new ListViewItem(new string[] { job.Id.ToString(), job.Name.ToString(), job.Status.ToString() });
        }
        private void UpdateListContents()
        {
            this.jobListView.Items.Clear();

            var visibleJobs = from item in this.jobs
                              where (this.JobFilter & item.Status) == item.Status
                              select item;

            foreach (var job in visibleJobs)
            {
                ListViewItem item = this.GetItemFromJob(job);
                this.jobListView.Items.Add(item);
            }
        }
        #endregion
        #region Properties
        /// <summary>
        /// Gets or sets the filter applied to visible jobs.
        /// </summary>
        public JobStatus JobFilter
        {
            get
            {
                return this.jobFilter;
            }
            set
            {
                this.jobFilter = value;
                this.OnJobFilterChanged(null);
            }
        }
        /// <summary>
        /// Gets or sets the <see cref="Job"/> that is currently selected.
        /// </summary>
        public Job SelectedJob
        {
            get
            {
                return this.selectedJob;
            }
            set
            {
                this.selectedJob = value;
            }
        }
        #endregion


    }
}
